<template>
    <el-collapse v-model="expanded" class="collapse">
        <el-collapse-item
            :name="title"
            :title="`${title}${elements ? ` (${elements.length})` : ''}`"
        >
            <template #icon>
                <Creation
                    v-if="blockType"
                    :block-type="blockType"
                    :parent-path-complete="parentPathComplete"
                    :ref-path="elements?.length ? elements.length - 1 : undefined"
                />
            </template>

            <Element
                v-for="(element, elementIndex) in filteredElements"
                :key="elementIndex"
                :section="section"
                :block-type="blockType"
                :parent-path-complete="parentPathComplete"
                :element
                :element-index
                @remove-element="removeElement(elementIndex)"
                @move-element="
                    (direction: 'up' | 'down') =>
                        moveElement(
                            elements,
                            element.id,
                            elementIndex,
                            direction,
                        )
                "
            />
        </el-collapse-item>
    </el-collapse>
</template>

<script setup lang="ts">
    import {computed, inject, ref} from "vue";

    import * as YAML_UTILS from "@kestra-io/ui-libs/flow-yaml-utils";

    import {CollapseItem} from "../../utils/types";

    import Creation from "./buttons/Creation.vue";
    import Element from "./Element.vue";
    import {
        CREATING_TASK_INJECTION_KEY, FLOW_INJECTION_KEY,
        PARENT_PATH_INJECTION_KEY, REF_PATH_INJECTION_KEY
    } from "../../injectionKeys";
    import {SECTIONS_MAP} from "../../../../utils/constants";

    const emits = defineEmits(["remove", "reorder"]);

    const flow = inject(FLOW_INJECTION_KEY, ref(""));

    const props = defineProps<CollapseItem>();
    const filteredElements = computed(() => props.elements?.filter(e => e !== undefined) ?? []);
    const expanded = ref<CollapseItem["title"]>(props.title);

    const parentPath = inject(PARENT_PATH_INJECTION_KEY, "");
    const refPath = inject(REF_PATH_INJECTION_KEY, undefined);
    const creatingTask = inject(CREATING_TASK_INJECTION_KEY, ref(false));

    const parentPathComplete = computed(() => {
        return `${[
            [
                parentPath,
                creatingTask.value && refPath !== undefined
                    ? `[${refPath + 1}]`
                    : refPath !== undefined
                        ? `[${refPath}]`
                        : undefined,
            ].filter(Boolean).join(""),
            props.section
        ].filter(p => p.length).join(".")}`;
    });

    const removeElement = (index: number) => {
        emits(
            "remove",
            YAML_UTILS.deleteBlockWithPath({
                source: flow.value,
                path: `${parentPathComplete.value}[${index}]`,
            }),
        );
    };

    const moveElement = (
        items: Record<string, any>[] | undefined,
        elementID: string,
        index: number,
        direction: "up" | "down",
    ) => {
        const keyName = props.title === "Plugin Defaults" ? "type" : "id";
        if (!items || !flow) return;
        if (
            (direction === "up" && index === 0) ||
            (direction === "down" && index === items.length - 1)
        )
            return;

        const newIndex = direction === "up" ? index - 1 : index + 1;

        emits(
            "reorder",
            YAML_UTILS.swapBlocks({
                source:flow.value,
                section: SECTIONS_MAP[props.title.toLowerCase() as keyof typeof SECTIONS_MAP],
                key1:elementID,
                key2:items[newIndex][keyName],
                keyName,
            }),
        );
    };
</script>

<style scoped lang="scss">
@import "../../styles/code.scss";
</style>
